PIC, SHIFT REG AND L.C.D.

With one of my designs I used a PIC16F84 as I did not want to use (waste) an 87X or buy a serial l.c.d. (too dear for alphanumerics) so I extended a routine for 8-bit shift registers I developed, added some of John Becker's l.c.d. bits and ended up with a routine to talk to intelligent l.c.d.s. it only uses three I/O pins and although not optimised, works ok. The code is given below.

I would recommend TK3, as a tutor and development tool, excellent value, well done, many thanks. 

Graham Card, via email


;allows an intelligent LCD to be used via two cheap 4094BE 8 bit, cascaded shift registers.
;uses only three PIC I/O pins & 8 bit LCD data transfer, no need for BCD gymnastics!
;very short code needed to initialise LCD
;seven outputs from S/Reg 1 available for warning leds / other equipment
;link latch & clock lines on the shift registers & connect pin 9(O's) of first S/Reg to pin 2 (data) of next
;data ripples through S/Reg 1 into S/Reg 2. min LCD timing is covered by this 16 bit loop.
;LCD is on S/Reg 2 in this prog, S/Reg O0 to lcd D0 etc, enable of lcd to pin 4 (O0) of S/Reg 1
;luckily? LCD enable & S/Reg latch work opposite so connect both to porta 0 (or your pin assignment)
;remove demo message / table, & message display section if not reqd, then add your code. 
;shift register section is for serial shift registers not just lcd's. (check latch & clock requirements of yours)
;this demo = PIC 16F84 porta 0 = latch, a1 = data, a2 = clock


#DEFINE PAGE0   BCF 3,5
#DEFINE PAGE1   BSF 3,5

W:	.EQU 0
F:	.EQU 1
PCL:	.EQU 2
PORTA:	.EQU 5
TRISA:	.EQU 5
LOOP:	.EQU 12		
COUNT:	.EQU 13
TEMP:	.EQU 14

	.ORG $0004
	.ORG $0005

	CLRF PORTA
	PAGE1
	CLRF TRISA	;porta as outputs    
	PAGE0
	
	GOTO SETUP      ;bypass tables
        
;********message, not mandatory! max 40 characters per lcd row*********************

MSG:	ADDWF PCL,F	;add value of loop to pcl
	RETLW 'T'
	RETLW 'K'
	RETLW '3'
	RETLW '!'
	RETLW ' '
	RETLW 'B'	
	RETLW 'R'
	RETLW 'I'
	RETLW 'L'
	RETLW 'L'
	RETLW 'I'
	RETLW 'A'	
	RETLW 'N'
	RETLW 'T'	
	RETLW ' '
	RETLW 'U'
	RETLW 'S'
	RETLW 'E'
	RETLW 'F'
	RETLW 'U'
	RETLW 'L'
	RETLW ' '
	RETLW '&'
	RETLW ' '	
	RETLW 'E'
	RETLW 'X'
	RETLW 'C'
	RETLW 'E'
	RETLW 'L'
	RETLW 'L'
	RETLW 'E'
	RETLW 'N'	
	RETLW 'T'
	RETLW ' '
	RETLW 'V'
	RETLW 'A'
	RETLW 'L'
	RETLW 'U'
	RETLW 'E'
	GOTO MOVE	;escape from this table  

;*********************LCD initialisation *******************************

SETUP:	CALL PAUSIT     ;perform first delay to wait for lcd to wake up!
	MOVLW %00111100 ;set for 2 lines 8-bit 5x10 dot operation
	CALL COM
	MOVLW %00000110 ;set entry mode to increment each address
	CALL COM
	MOVLW %00001100 ;set display on, cursor off, blink off
	CALL COM
	MOVLW %00000001 ;clear display
	CALL COM
	MOVLW %10000000	;set disply start address
	CALL COM
	CALL PAUSIT	;allow time for display to initialise!

;***********************display & move message *******************************
 
LCDMSG:	MOVF LOOP,W	;get table address (LOOP cleared & tested in PAUSIT)
	CALL MSG	;get message letter
	CALL CHAR	;and send it
	INCF LOOP,F	;inc loop
	GOTO LCDMSG	;loop to end of table

MOVE:	MOVLW 20	;this section for message only
	MOVWF TEMP	
DEC:	CALL PAUSIT
	DECFSZ TEMP,F
	GOTO DEC
	MOVLW %00011000	;LCD command to rotate text one place to the left
	CALL COM	;send COMmand register select bit
	GOTO MOVE

;*********************output to lcd display **************************************

;NUM:	ADDLW 48	;convert NUMerals to ascii 
CHAR:	CALL SHIFT	;sends & displays CHARacter data
	MOVLW 1		;sets RS line &/or other equipment on/off
	CALL SHIFT	;send register select byte
	BSF PORTA,0	;output data from shift register & enable lcd 
	RETURN
COM:	CALL SHIFT	;sends & actions COMmand instructions. 
	CLRW		;clears RS line &/or other equipment on/off
	CALL SHIFT	;send register select byte
	BSF PORTA,0	;output data from shift register & enable lcd
	RETURN
  	
;*************************Shift register ***********************************

SHIFT: 	MOVWF TEMP	;load temp with byte to send. make sure w contains byte to send
	BSF COUNT,3	;set count to shift 8 bits (COUNT cleared & tested in PAUSIT)
	BCF PORTA,0	;latch & prepare shift reg(s) to receive data, also is EN-line on lcd	
SEND0:	BTFSC TEMP,7	;is MSB set?
	GOTO SEND1	;yes, send a one
	BCF PORTA,1	;
	GOTO CLOCK	;no, send a 0 data bit
SEND1:	BSF PORTA,1	;send a 1 data bit
CLOCK:	BSF PORTA,2	;clock on
	BCF PORTA,2	;clock off
BITCNT:	RLF TEMP,F	;move next bit to send
	DECFSZ COUNT,F	;is COUNT zero, all bits sent?
	GOTO SEND0	;no, send next bit
	;BSF PORTA,0	;output data from shift reg (use this line for single S/Reg only progs)
	RETURN		;yes return to call	

;**********************timing section**********************************************

PAUSIT:	BSF LOOP,5	;delay seems to work ok at up to 6mhz crystal, adjust to suit yours
TIME:	CLRF COUNT
AGAIN:	DECFSZ COUNT,F
	GOTO AGAIN
	DECFSZ LOOP,F
	GOTO TIME
	RETURN

	.END







